using System;

namespace Fadd.Components
{
    /// <summary>
    /// Base interface used to provide components.
    /// </summary>
    public interface IComponentProvider
    {
        /// <summary>
        /// Add a component.
        /// </summary>
        /// <typeparam name="InterfaceType">Interface type, used to request components.</typeparam>
        /// <typeparam name="InstanceType">Instance type, used to create component.</typeparam>
        /// <param name="constructorParameters">Extra parameters used in the constructor.</param>
        void Add<InterfaceType, InstanceType>(params Parameter[] constructorParameters);

        /// <summary>
        /// Add an existing instance.
        /// </summary>
        /// <param name="instance"></param>
        /// <typeparam name="T">Interface type being requested when getting this component</typeparam>
        /// <exception cref="ArgumentException"></exception>
        void AddInstance<T>(object instance);

        /// <summary>
        /// Checks whether a specific type exists (loaded or not loaded)
        /// </summary>
        /// <param name="interfaceType">Interface to check.</param>
        bool Contains(Type interfaceType);

        /// <summary>
        /// Checks whether a specific type exists (loaded or not loaded)
        /// </summary>
        /// <param name="name">Name of component.</param>
        bool Contains(string name);

        /// <summary>
        /// Gets a component.
        /// </summary>
        /// <remarks>
        /// The component will be created if needed.
        /// </remarks>
        /// <typeparam name="T">Type of component (interface)</typeparam>
        /// <returns>Component if found; otherwise null.</returns>
        T Get<T>() where T : class;
    }
}